package com.pan.operation;

import com.pan.seed.Jone;
import com.pan.seed.Sofia;
import lombok.extern.slf4j.Slf4j;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 *
 * 这个类主要用来演示如何使用反射
 * 操作的对象为Jone
 * @author by panstark
 * @description
 * @notice
 * @date 2021/4/29
 */
@Slf4j
public class Reflection {


    public void getInfo(Class aClass){

        /**
         * 我是谁？
         */
        String name = aClass.getName();
        log.info("name:{}",name);

        /**
         * 我的构造器
         */
        Constructor<?>[] constructors = aClass.getConstructors();
        Arrays.stream(constructors).forEach(x->{
            log.info("constructors:",x.getName());
        });

        /**
         * 我的属性
         */
        Field[] declaredFields = aClass.getDeclaredFields();
        Arrays.stream(declaredFields).forEach(x->{
            log.info("feilds:{}",x.getName());
        });

        /**
         * 我的方法
         */
        Method[] methods = aClass.getDeclaredMethods();
        Arrays.stream(methods).forEach(x->{
            log.info("methods:{}",x.getName());
        });

        /**
         * 我被谁加载到这个世界的
         */
        ClassLoader classLoader = aClass.getClassLoader();
        log.info("classLoader:{}",classLoader.toString());

        /**
         * 我有哪些帽子？
         */
        Annotation[] annotations = aClass.getAnnotations();
        Arrays.stream(annotations).forEach(x->{
            log.info("annotations:{}",x.annotationType());
        });
    }

    /**
     * 通过反射来调用
     * 一个对象的方法，所以必须现有一个对象
     *
     * @param aClass
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     * @throws InstantiationException
     */
    public void doSomething(Class aClass) {

        Object object = null;
        try {
            object = aClass.newInstance();

            Method[] methods = aClass.getDeclaredMethods();

            for (int i = 0; i < methods.length; i++) {

                Method method = methods[i];
                //调用selfIntroduction方法相同
                if("selfIntroduction".equals(method.getName())){
                    method.invoke(object,"Sofia");
                    //调用sayNoInMyHeart方法
                }else if("sayNoInMyHeart".equals(method.getName())){
                    //对于私人方法，你一定要设置为true，才能调用
                    method.setAccessible(true);
                    method.invoke(object);
                }
            }
        } catch (InstantiationException | InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }


    public static void main(String[] args) {
        Reflection reflection= new Reflection();
        reflection.getInfo(Sofia.class);
        reflection.doSomething(Sofia.class);
    }

}
